package com.fengxing.ams.web.facade;

import java.math.BigInteger;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.fengxing.ams.pub.AMSException;
import com.fengxing.ams.pub.manager.intf.IConfigManager;
import com.fengxing.ams.pub.persistence.DynamicSpecifications;
import com.fengxing.ams.pub.persistence.SearchFilter;
import com.fengxing.ams.pub.persistence.SearchFilter.Operator;
import com.fengxing.ams.web.action.view.DistributionQueryVO;
import com.fengxing.ams.web.action.view.EnrollScoreQueryVO;
import com.fengxing.ams.web.action.view.EnterpriseQueryVO;
import com.fengxing.ams.web.action.view.OrderCheckVO;
import com.fengxing.ams.web.action.view.OrderForCheckVO;
import com.fengxing.ams.web.action.view.SolutionStudentCondition;
import com.fengxing.ams.web.action.view.StudentsQueryParamVO;
import com.fengxing.ams.web.common.IContextManager;
import com.fengxing.ams.web.facade.intf.IStudentFacade;
import com.fengxing.ams.web.facade.mouble.college.CollegeVO;
import com.fengxing.ams.web.facade.mouble.company.CompanyImportVO;
import com.fengxing.ams.web.facade.mouble.company.CompanyVO;
import com.fengxing.ams.web.facade.mouble.company.EnterpriseNotifyVO;
import com.fengxing.ams.web.facade.mouble.company.ICompanyDAO;
import com.fengxing.ams.web.facade.mouble.company.ICompanyImportDAO;
import com.fengxing.ams.web.facade.mouble.company.IEnterpriseNotifyDAO;
import com.fengxing.ams.web.facade.mouble.luqu.MajorVO;
import com.fengxing.ams.web.facade.mouble.major.MajorDescriptionVO;
import com.fengxing.ams.web.facade.mouble.notification.INotificationDAO;
import com.fengxing.ams.web.facade.mouble.notification.NotificationVO;
import com.fengxing.ams.web.facade.mouble.order.IOrderHistoryDAO;
import com.fengxing.ams.web.facade.mouble.order.IStatusFlowDAO;
import com.fengxing.ams.web.facade.mouble.order.OrderHistoryVO;
import com.fengxing.ams.web.facade.mouble.order.StatusFlowVO;
import com.fengxing.ams.web.facade.mouble.student.IStudentSCMDAO;
import com.fengxing.ams.web.facade.mouble.student.StudentSCMVO;
import com.fengxing.ams.web.facade.mouble.student.StudentVO;
import com.fengxing.ams.web.facade.mouble.upload.IUploadDAO;
import com.fengxing.ams.web.facade.mouble.upload.IUploadDetailDAO;
import com.fengxing.ams.web.facade.mouble.upload.UploadDetailVO;
import com.fengxing.ams.web.facade.mouble.upload.UploadVO;
import com.fengxing.ams.web.facade.mouble.user.IRoleDAO;
import com.fengxing.ams.web.facade.mouble.user.IUserDAO;
import com.fengxing.ams.web.facade.mouble.user.UserVO;

@Component
@Transactional
public class StudentFacade implements IStudentFacade {

	@Autowired
	IConfigManager configManager;
	
	@Autowired
	IStudentSCMDAO studentSCMDAO;
	
	@Autowired
	ICompanyDAO companyDAO;
	
	@Override
	public StudentSCMVO queryProfileById(String email) {
		return this.studentSCMDAO.findByStudentId(email);
	}

	@Override
	public List<BigInteger> getGendarTotal(Integer college_id) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BigInteger getApplyStudentTotal(Integer collegeId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStduentByScore(EnrollScoreQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStduentByScoreGroup(EnrollScoreQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Integer> queryLocationDistribution(
			DistributionQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<CollegeVO, Integer> queryLocationTop10College(
			DistributionQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<MajorVO, Integer> queryTop10MajorByCollege(
			DistributionQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Integer> querySubjectRatio(Integer i) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<String, Integer> queryBatchDistribution(
			DistributionQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Map<MajorDescriptionVO, Integer> queryMajorDistribution(
			DistributionQueryVO queryVO) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStudentByRangeInnerJoinEnrollment(
			Map<Integer, Integer> scoreMaps, int i, String subject, String batch) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStudentByCollegeIdAndDescriptionId(
			Map<Integer, Integer> configMap, Integer tholder,
			Map<Integer, Integer> scoreMaps, Integer range, String subject,
			String batch, List<Integer> collegeIds, List<Integer> descriptionIds) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStduentsBySolutionCondition(
			SolutionStudentCondition view) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<StudentVO> queryStudentByScoreRange(
			Map<Integer, Integer> config, Integer thredhold,
			Map<Integer, Integer> scoreMaps, Integer highLine, Integer lowLine,
			String subject, List<String> batchs, List<Integer> collegeIds,
			List<Integer> descriptionIds, List<String> collegeTyps, String q_2,
			String q_9, String q_y) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public CompanyVO queryCompanyByStudentId(String email) {
		return companyDAO.findByStudentId(email);
	}

	@Autowired
	IOrderHistoryDAO orderHistoryDAO;
	
	@Override
	@Transactional(readOnly = false)
	public void orderApply(StudentSCMVO student, CompanyVO company) {
		//首先检查是否已经有申请记录，如果有则直接抛出异常
		//通过学生id去查找
		CompanyVO db = this.companyDAO.findByStudentId(student.getId());
		if (db != null) {
			//看状态是否为1：审核不通过
			if (db.getStatus().equals(Integer.valueOf(1)) || db.getStatus().equals(Integer.valueOf(2))
					) {
				//删除旧的签约信息
				this.companyDAO.delete(db.getId());
			} else {
				//申请失败
				throw new AMSException("您的签约信息正在审批中，本次提交失败！");
			}
		}
		//对学生信息进行补全
		String majorName = student.getMajorName();
		student.setMajorName(majorName);
		String collegeName = student.getCollegeName();
		Integer collegeId = this.configManager.getCollegeId(collegeName);
		if (collegeId == null) {
			throw new AMSException("院校专业信息不正确！");
		}
		student.setCollegeId(collegeId);//补全学院id
		student.setStatus(0);
		//对学生信息进行更新操作
		this.studentSCMDAO.save(student);
		
		//对company信息补全
		company.setStudent(student);
		company.setStudentCollege(student.getCollegeId());
		company.setStatus(0);
		company.setRemark(null);
		Date now = Calendar.getInstance().getTime();
		company.setCreatedDate(now);
		
		this.companyDAO.save(company);
		
		//插入历史表
		OrderHistoryVO history = new OrderHistoryVO();
		history.setCompany(company.getName());
		history.setCreateDate(now);
		history.setRemark(company.getRemark());
		history.setStatus(company.getStatus());
		history.setStudentId(student.getId());
		orderHistoryDAO.save(history);
		
		//给管理员发通知
		notificationSave(student, STUDENT_APPLY);
	}
	
	private static final String STUDENT_APPLY = "{0}提交了签约申请！";
	
	private static final String STUDENT_REAPPLY = "{0}提交了违约申请！";
	
	private static final String CHECK_ORDER = "{0}审批了{1}的申请，审批结果：{2}！";
	@Autowired
	INotificationDAO notificationDAO;

	private void notificationSave(StudentSCMVO student, String action) {
		//通知学院管理员
		NotificationVO vo1 = new NotificationVO();
		vo1.setAction("/order/checkOne");
		vo1.setCreatedDate(new Date());
		vo1.setParam(student.getId());
		vo1.setReaded("未读");
		vo1.setTitle(MessageFormat.format(action, student.getName()));
		UserVO userVO = this.contextManager.getManagerUserVO(student.getCollegeId());
		vo1.setUserId(userVO.getUserId());
		
		this.notificationDAO.save(vo1);
		
		//通知就业中心管理员
		NotificationVO vo2 = new NotificationVO();
		vo2.setAction("/order/checkOne");
		vo2.setCreatedDate(new Date());
		vo2.setParam(student.getId());
		vo2.setReaded("未读");
		vo2.setTitle(MessageFormat.format(action, student.getName()));
		UserVO supperManagerUserVO = this.contextManager.getSupperManagerUserVO();
		vo2.setUserId(supperManagerUserVO.getUserId());
		
		this.notificationDAO.save(vo2);
	}

	@Override
	public List<OrderForCheckVO> queryOrdersForCheck(Integer collegeId) {
		List<CompanyVO> companyList = this.companyDAO.queryOrdersForCheck(collegeId);
		return convertToView(companyList);
	}

	private List<OrderForCheckVO> convertToView(List<CompanyVO> companyList) {
		List<OrderForCheckVO> list = new ArrayList<OrderForCheckVO> ();
		for (CompanyVO company : companyList) {
			OrderForCheckVO vo = new OrderForCheckVO();
			
			vo.setCompanyName(company.getName());
			vo.setCompanyTelephone(company.getTelephone());
			vo.setCreatedDate(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(company.getCreatedDate()));
			vo.setId(company.getId());
			vo.setMajorName(company.getStudent().getMajorName());
			vo.setMobile(company.getStudent().getMobile());
			vo.setName(company.getStudent().getName());
			vo.setStudentId(company.getStudent().getId());
			
			list.add(vo);
		}
		return list;
	}

	@Override
	public List<OrderForCheckVO> queryOrdersForCheck() {
		List<CompanyVO> companyList = this.companyDAO.queryOrdersForCheck();
		return convertToView(companyList);
	}

	@Override
	public CompanyVO queryOrderForCheckOne(String studentId) {
		CompanyVO companyVO = this.companyDAO.findByStduentId(studentId);
		if (companyVO == null) {
			companyVO = new CompanyVO();
			companyVO.setStudent(this.studentSCMDAO.findOne(studentId));
		}
		return companyVO;
	}

	@Override
	public List<OrderHistoryVO> queryTimeLines(String id) {
		return this.orderHistoryDAO.queryTimeLineByStudentId(id);
	}

	@Autowired
	IStatusFlowDAO statusFlowDAO;
	
	@Override
	@Transactional(readOnly = false)
	public void checkOrder(OrderCheckVO input) {
		//查询出当前状态
		CompanyVO order = this.companyDAO.findOne(input.getId());
		if (order == null) {
			throw new AMSException("当前操作的资源不存在！");
		}
		//根据当前状态获取下一状态
		StatusFlowVO nextStatus = this.statusFlowDAO.findNextStatus(order.getStatus(), input.getType());
		if (nextStatus == null) {
			throw new AMSException("当前流程结束，无法重复审批！");
		}
		//检查权限
		if (!this.contextManager.getUserVO().getRoleIdList().contains(Long.valueOf(nextStatus.getRoleId() + 0L))) {
			throw new AMSException("您没有当前状态的审批权限！");
		}
		//更新当前记录状态及remark字段
		this.companyDAO.updateStatus(input.getRemark(), input.getId(), nextStatus.getNextStatus());
		//更新student状态表
		this.studentSCMDAO.updateStatus(nextStatus.getNextStatus(), order.getStudent().getId());
		//将当前记录移入历史表中
		OrderHistoryVO history = new OrderHistoryVO();
		history.setCompany(order.getName());
		history.setCreateDate(new Date());
		history.setRemark(input.getRemark());
		history.setStatus(nextStatus.getNextStatus());
		history.setStudentId(order.getStudent().getId());
		
		orderHistoryDAO.save(history);
		
		notificationSave(order.getStudent(), nextStatus, CHECK_ORDER);
	}
	
	private void notificationSave(StudentSCMVO student,
			StatusFlowVO nextStatus, String checkOrder) {
		//当前登录用户
		UserVO currentUserVO = this.contextManager.getUserVO();
		String title = MessageFormat.format(checkOrder, currentUserVO.getName(), student.getName(), this.configManager.getStatusDesc(nextStatus.getNextStatus()));
		//通知学生
		NotificationVO vo1 = new NotificationVO();
		vo1.setAction("/order/timeline");
		vo1.setCreatedDate(new Date());
		vo1.setReaded("未读");
		vo1.setTitle(title);
		//查询userId
		UserVO studnetUserVO = this.userDAO.findByEmail(student.getId());
		vo1.setUserId(studnetUserVO.getUserId());
		
		this.notificationDAO.save(vo1);
		
		if (currentUserVO.getRoleIdList().contains(Long.valueOf(5L))) {
			//通知就业中心管理员
			NotificationVO vo2 = new NotificationVO();
			vo2.setAction("/order/checkOne");
			vo2.setCreatedDate(new Date());
			vo2.setParam(student.getId());
			vo2.setReaded("未读");
			vo2.setTitle(title);
			UserVO supperManagerUserVO = this.contextManager.getSupperManagerUserVO();
			vo2.setUserId(supperManagerUserVO.getUserId());
			this.notificationDAO.save(vo2);
		}
		
	}

	@Autowired
	private IUploadDAO uploadDAO;

	@Override
	@Transactional(readOnly = false)
	public void save(UploadVO uploadVO) {
		this.uploadDAO.save(uploadVO);
	}

	@Override
	public List<UploadVO> queryUploadList(UploadVO uploadVO) {
		return this.uploadDAO.findAllSortByUploadTime(uploadVO.getType());
	}

	@Override
	public List<UploadVO> queryUploadsForParse() {
		return this.uploadDAO.queryUploadsForParse();
	}

	@Override
	public void updateUploadStatusAndRemark(Integer id, String status, String remark) {
		this.uploadDAO.updateUploadStatusAndRemark(id, status, remark);
	}
	
	@Autowired
	IUploadDetailDAO uploadDetailVO;

	@Override
	public List<UploadDetailVO> queryUploadDetail(Integer id) {
		return this.uploadDetailVO.queryUploadDetail(id);
	}

	@Override
	public Page<StudentSCMVO> queryStudentsList(StudentsQueryParamVO param) {
		Sort sort = new Sort(Sort.Direction.DESC, new String[]{"outDate"});
		List<SearchFilter> searchFilterList = new ArrayList<SearchFilter>();
		SearchFilter filter = null;
		
		if (StringUtils.isNotBlank(param.getId())) {
			filter  = new SearchFilter("id", Operator.EQ, param.getId(), null);
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getEnterDate())) {
			filter  = new SearchFilter("enterDate", Operator.EQ, param.getEnterDate(), null);
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getOutDate())) {
			filter  = new SearchFilter("outDate", Operator.EQ, param.getOutDate(), null);
			searchFilterList.add(filter);
		}
		
		if (param.getStatus() != null) {
			filter  = new SearchFilter("status", Operator.EQ, param.getStatus(), null);
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getName())) {
			filter  = new SearchFilter("name", Operator.EQ, param.getName(), null);
			searchFilterList.add(filter);
		}
		
		if (param.getMajorName() != null && !param.getMajorName().isEmpty()) {
			Integer[] major_idIntArr = new Integer[param.getMajorName().size()];
			for (int i = 0; i < param.getMajorName().size(); i++) {
				major_idIntArr[i] = Integer.valueOf(param.getMajorName().get(i));
			}
			filter  = new SearchFilter("majorId", Operator.IN, major_idIntArr);
			searchFilterList.add(filter);
		}
		
		if (param.getDegree() != null && !param.getDegree().isEmpty()) {
			filter  = new SearchFilter("degree", Operator.IN, param.getDegree().toArray(new String[param.getDegree().size()]));
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getSortField())) {
			Direction direction = null;
			if (param.getSortOrder().equals("descend")) {
				direction = Sort.Direction.DESC;
			} else {
				direction = Sort.Direction.ASC;
			}
			sort = new Sort(direction, new String[]{param.getSortField()});
		}
		PageRequest pr = new PageRequest(param.getCurrent()-1, param.getPageSize(), sort);
		
		Specification<StudentSCMVO> spec = DynamicSpecifications.bySearchFilter(
				searchFilterList, StudentSCMVO.class);
		return this.studentSCMDAO.findAll(spec, pr);
	}

	@Autowired
	IUserDAO userDAO;
	@Autowired
	IRoleDAO roleDAO;

	@Autowired
	private ICompanyImportDAO companyImportDAO;
	
	@Override
	public void studentsDelete(StudentsQueryParamVO param) {
		if (param.getIds() == null || param.getIds().isEmpty())
			return;
		//删除学生信息
		this.studentSCMDAO.deleteByIds(param.getIds());
		this.orderHistoryDAO.deleteAllByIds(param.getIds());
		this.companyDAO.deleteAllByIds(param.getIds());
		//删除用户信息
		List<UserVO> users = this.userDAO.findListByEmail(param.getIds());
		for (UserVO user : users) {
			this.userDAO.delete(user);
		}
		//删除学号
		this.configManager.deleteStudentIds(param.getIds());
		
	}

	@Override
	public void orderReApply(StudentSCMVO student, CompanyVO company) {
		//首先检查是否已经有申请记录，如果有则直接抛出异常
				//通过学生id去查找
				CompanyVO db = this.companyDAO.findByStudentId(student.getId());
				if (db == null)
					throw new AMSException("未提交签约申请，无法发起违约！");
				
				//看状态是否为 4:就业处审批通过 6 违约院系不通过 7 就业不通过 9 违约通过
				if (db.getStatus().equals(Integer.valueOf(4)) || db.getStatus().equals(Integer.valueOf(6))
						|| db.getStatus().equals(Integer.valueOf(7)) || db.getStatus().equals(Integer.valueOf(9))) {
					//删除旧的签约信息
					this.companyDAO.delete(db.getId());
				} else {
					//申请失败
					throw new AMSException("您的签约信息正在审批中，本次提交失败！");
				}
				//对学生信息进行补全
				String majorName = student.getMajorName();
				student.setMajorName(majorName);
				String collegeName = student.getCollegeName();
				Integer collegeId = this.configManager.getCollegeId(collegeName);
				if (collegeId == null) {
					throw new AMSException("院校专业信息不正确！");
				}
				student.setCollegeId(collegeId);//补全学院id
				student.setStatus(5);
				//对学生信息进行更新操作
				this.studentSCMDAO.save(student);
				
				//对company信息补全
				company.setStudent(student);
				company.setStudentCollege(collegeId);
				company.setStatus(5);
				company.setRemark(null);
				Date now = Calendar.getInstance().getTime();
				company.setCreatedDate(now);
				
				this.companyDAO.save(company);
				
				//插入历史表
				OrderHistoryVO history = new OrderHistoryVO();
				history.setCompany(company.getName());
				history.setCreateDate(now);
				history.setRemark(company.getRemark());
				history.setStatus(company.getStatus());
				history.setStudentId(student.getId());
				orderHistoryDAO.save(history);
				
				notificationSave(student, STUDENT_REAPPLY);
	}

	@Override
	public Page<CompanyImportVO> queryEnterpriseList(EnterpriseQueryVO param) {
		Sort sort = new Sort(Sort.Direction.DESC, new String[]{"id"});
		List<SearchFilter> searchFilterList = new ArrayList<SearchFilter>();
		SearchFilter filter = null;
		
		if (this.contextManager.getUserVO().getRoleIdList().contains(Long.valueOf(5L))) {
			filter  = new SearchFilter("collegeId", Operator.EQ, this.contextManager.getUserVO().getCollegeId(), null);
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getName())) {
			filter  = new SearchFilter("name", Operator.LIKE, "%"+param.getName()+"%", null);
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getStockMarket())) {
			filter  = new SearchFilter("stockMarket", Operator.EQ, param.getStockMarket(), null);
			searchFilterList.add(filter);
		}
		
		if (param.getProvince() != null && !param.getProvince().isEmpty()) {
			filter  = new SearchFilter("province", Operator.IN, param.getProvince().toArray());
			searchFilterList.add(filter);
		}
		
		if (param.getCity() != null && !param.getCity().isEmpty()) {
			filter  = new SearchFilter("city", Operator.IN, param.getCity().toArray());
			searchFilterList.add(filter);
		}
		if (param.getIndustry() != null && !param.getIndustry().isEmpty()) {
			filter  = new SearchFilter("industry", Operator.IN, param.getIndustry().toArray());
			searchFilterList.add(filter);
		}
		
		if (StringUtils.isNotBlank(param.getSortField())) {
			Direction direction = null;
			if (param.getSortOrder().equals("descend")) {
				direction = Sort.Direction.DESC;
			} else {
				direction = Sort.Direction.ASC;
			}
			sort = new Sort(direction, new String[]{param.getSortField()});
		}
		PageRequest pr = new PageRequest(param.getCurrent()-1, param.getPageSize(), sort);
		
		Specification<CompanyImportVO> spec = DynamicSpecifications.bySearchFilter(
				searchFilterList, CompanyImportVO.class);
		return this.companyImportDAO.findAll(spec, pr);
	}

	@Override
	public void enterpriseDelete(EnterpriseQueryVO param) {
		this.companyImportDAO.deleteByIds(param.getIds());
		//删除学号
		this.configManager.deleteStudentIds(param.getIds());
	}

	@Autowired
	IEnterpriseNotifyDAO enterpriseNotifyDAO;
	@Autowired
	IContextManager contextManager;
	@Override
	public void saveNotify(EnterpriseNotifyVO param) {
		enterpriseNotifyDAO.save(param);
	}

	@Override
	public void enterpriseCreate(CompanyImportVO param) {
		//插入主键id
		//查询最大id的值
		String id = this.companyImportDAO.findMaxId();
		param.setId(String.valueOf(Integer.valueOf(id) + 1));
		param.setCollegeId(this.contextManager.getUserVO().getCollegeId());
		this.companyImportDAO.save(param);
	}

}
